#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

// getchar
// putchar

int hex_digit(int n) {
	if('0' <= n && n <= '9') {
		return n - '0';
	}
	
	if('a' <= n && n <= 'f') {
		return n - 'a' + 10;
	}
	
	if('A' <= n && n <= 'F') {
		return n - 'A' + 10;
	}
	
	fprintf(stderr, "X\n");
	exit(-1);
}

void skip_comment() {
	int nyb;
	
	do {
		nyb = getchar();
		if(nyb == EOF) exit(-1);
		if(nyb == '\n') return;
	} while(1);
}

#define MAXSIZE 4096
#define MAXLBLS 100

void read_lbl(unsigned char *lbl) {
	int nyb;
	int i = 0;

	do {
		nyb = getchar();
		
		if(nyb == ' ' || nyb == '\t' || nyb == '\n') {
		        return;
		}
		
		lbl[i++] = nyb;
	} while(1);
}

#define MAXREFS 256

unsigned char lbl[MAXLBLS][32] = { { 0 } };
int lbl_place[MAXLBLS] = { 0 };
int lbl_len = 0;

int lookup_label(unsigned char *label) {
	for(int i = 0; i < lbl_len; i++) {
		if(!strcmp((char*)lbl[i],(char*)label))
			return lbl_place[i];
	}

	fprintf(stderr, "fail <%s>\n", label);
	exit(-1);
}

int main(void) {
	int nyb, oct;
	
	unsigned char c[MAXSIZE] = { 0 };
	int len = 0;
	int i;

	unsigned char ref_sigil[MAXREFS] = { 0 };
	unsigned char ref_lbl[MAXREFS][32] = { { 0 } };
	int ref_pos[MAXREFS] = { 0 };
	int ref_len = 0;

	int8_t u8;
	int16_t u16;
	int32_t u32;

	do {
		nyb = getchar();
		if(nyb == EOF) {
			break;
		}
		else if(nyb == '#') {
			skip_comment();
			continue;
		}
		else if(nyb == ' ' || nyb == '\t' || nyb == '\n') {
			continue;
		}
		else if(nyb == ':') {
			read_lbl(lbl[lbl_len]);
			lbl_place[lbl_len] = len;
			
			////
			fprintf(stderr, "LBL: <%s>\n", lbl[lbl_len]);
			
			lbl_len++;
			
			continue;
		}
		else if(nyb == '.' || nyb == '@' || nyb == '$' || nyb == '*') {
			ref_sigil[ref_len] = nyb;
			read_lbl(ref_lbl[ref_len]);
			
			////
			fprintf(stderr, "REF: [%c]<%s>\n", ref_sigil[ref_len], ref_lbl[ref_len]);
			
		        ref_pos[ref_len] = len;
			ref_len++;

			switch(nyb) {
			case '.':
				c[len++] = 0xFF;
				break;
				
			case '@':
				c[len++] = 0xFF;
				c[len++] = 0xFF;
				break;

			case '$':
				c[len++] = 0xFF;
				c[len++] = 0xFF;
				break;

			case '*':
				c[len++] = 0xFF;
				c[len++] = 0xFF;
				c[len++] = 0xFF;
				c[len++] = 0xFF;
				break;

			default:
				fprintf(stderr, "A\n");
				exit(-1);
			}

			continue;
		}
		
		nyb = hex_digit(nyb);
		oct = nyb << 4;
		nyb = getchar();
		nyb = hex_digit(nyb);
		oct |= nyb;

		c[len++] = oct;
	} while(1);

	for(i = 0; i < ref_len; i++) {
		switch(ref_sigil[i]) {
		case '.':
			u8 = lookup_label(ref_lbl[i]) - ref_pos[i] - 1;
			c[ref_pos[i]] = u8 & 0xFF;
			
			break;
			
		case '@':
			u16 = lookup_label(ref_lbl[i]) - ref_pos[i] + 2;
			c[ref_pos[i]+1] = u16 & 0xFF;
			c[ref_pos[i]+0] = (u16 >> 8) & 0xFF;
			
			break;
			
		case '*':
			u32 = lookup_label(ref_lbl[i]) - ref_pos[i] - 4;
			c[ref_pos[i]+0] = u32 & 0xFF;
			c[ref_pos[i]+1] = (u32 >> 8) & 0xFF;
			c[ref_pos[i]+2] = (u32 >> 16) & 0xFF;
			c[ref_pos[i]+3] = (u32 >> 24) & 0xFF;
			
			break;
			
		case '$':
			u16 = lookup_label(ref_lbl[i]);
			c[ref_pos[i]+1] = u16 & 0xFF;
			c[ref_pos[i]+0] = (u16 >> 8) & 0xFF;
			
			break;
			
		default:
			fprintf(stderr, "B\n");
			exit(-1);
		}
		
	}
	
        for(i = 0; i < len; i++) {
		putchar(c[i]);
	}
}
